Day 22 dp, 수학, 조건문, 배열
Day22 22단계 2023-11-11
1. 저주의 숫자 3
- 내 풀이 : 10진수 n번째까지 answer를 증가시키는 연산을 진행한다.
- 만약 answer가 3의 배수거나, 3을 포함한다면 이 조건을 만족하지 않을 때까지 1을 더한다.
class Solution {
public int solution(int n) {
int answer = 0;
for (int i = 1; i <= n; i++) {
answer++;
while (answer%3 == 0 || answer%10 == 3 || answer/10 == 3 || (answer/10)%10 == 3)
answer++;
}
return answer;
}
}
- 다른 사람 풀이 : answer가 3의 배수가 아니거나, answer를 String으로 바꿨을 때 3을 포함하지 않는 경우로 판별하였다.
- 위 경우가 아닐 때 for문의 인덱스를 1개 낮췄다
for (int i = 1; i <= n; i++) {
answer++;
if (answer%3 == 0 || String.valueOf(answer).contains("3"))
i--;
}
3. 겹치는 선분의 길이
- 내 풀이 : 모든 선분을 포함하는 범위를 지정해서 잡은 후, 그 int 배열을 좌표로 정한다.
- 각 선분들에 대해 좌표가 선분에 포함되면 전체 길이 배열에서 그 index에 해당하는 요소를 +1 해준다.
- 중복된 선분은 요소로 2를 가지고, 요소가 연속으로 2인 경우에 대해 두 요소의 (index+시작점)(=실제 점의 좌표)가 두 선분에 포함되는지 확인한다.
- 다른 사람들의 풀이를 보니 내 풀이가 복잡해진 이유는 좌표 그대로의 중복 횟수를 저장한게 아닌, 좌표를 배열의 index로 저장하는 과정에서 더 복잡해진 것 같다.
class Solution {
public int solution(int[][] lines) {
int start = Math.min(lines[2][0], Math.min(lines[0][0], lines[1][0]));
int end = Math.max(lines[2][1], Math.max(lines[0][1], lines[1][1]));
int[] arr = new int[end - start + 1];
for (int i = lines[0][0]; i <= lines[0][1]; i++) arr[i - start]++;
for (int i = lines[1][0]; i <= lines[1][1]; i++) arr[i - start]++;
for (int i = lines[2][0]; i <= lines[2][1]; i++) arr[i - start]++;
int answer = 0;
int same = 0;
a:for (int j = 0; j < arr.length -1; j++) {
if (arr[j] >= 2 && arr[j+1] >= 2) {
if ((j+start) >= lines[0][0] && (j+start) <= lines[0][1] &&
(j+1+start) >= lines[0][0] && (j+1+start) <= lines[0][1]) {
same++;
}
if ((j+start) >= lines[1][0] && (j+start) <= lines[1][1] &&
(j+1+start) >= lines[1][0] && (j+1+start) <= lines[1][1]) {
same++;
}
if ((j+start) >= lines[2][0] && (j+start) <= lines[2][1] &&
(j+1+start) >= lines[2][0] && (j+1+start) <= lines[2][1]) {
same++;
}
if(same >= 2) answer++;
}
}
return answer;
}
}
- 다른 사람 풀이 1: 문제에서 좌표의 범위가 -100 ~100이므로 해당 반복분 내에서 line에 포함되는 위치가 있으면 +1을 해준다.
- 더해준 값이 1보다 크면 answer를 +1 해준다.
int answer = 0;
for (int i = -100; i < 100; i++) {
int line = 0;
if (lines[0][0]<=i && lines[0][1]>i) line++;
if (lines[1][0]<=i && lines[1][1]>i) line++;
if (lines[2][0]<=i && lines[2][1]>i) line++;
if(line > 1) answer++;
}
return answer;
- 다른 사람 풀이 2 : HashMap을 사용했고, 전체 선분의 범위 시작과 끝 값에 대해 map의 key는 좌표로, value는 좌표가 포함된 횟수로 저장했다.
4. 유한소수 판별하기
- 내 풀이 : BigDecimal 클래스를 사용해서 scale() 메소드로 만약 유한 소수면 1을 반환하고, 무한 소수면 ArithmeticException 예외가 발생하므로 2를 반환했다.
- 속도가 매우 느리다(거의 모든 테스트에서 평균 1.5 ms 가 걸린다)
import java.math.BigDecimal;
class Solution {
public int solution(int a, int b) {
BigDecimal aBig = new BigDecimal(a);
BigDecimal bBig = new BigDecimal(b);
try {
if (aBig.divide(bBig).scale()>=0)
return 1;
} catch (ArithmeticException e) {
return 2;
}
return 2;
}
}
- 다른 사람들 풀이 : 분모를 2 나 5로 나눈 나머지가 0이 될 때까지 2와 5로 나눈 몫을 반환해서 계속 나눈다.
- 만약 2와 5로 계속 나눠서 나머지가 0인 결과값을 a로 나눈 몫이 1과 같으면 유한소수, 1과 다르다면(즉 전자의 숫자가 a의 공약수가 아니라면) 무한소수이다.
- 최대 공약수를 구하는 메소드를 따로 작성한 풀이도 있다.
- Day 2 사칙연산, 조건문, 배열#3. 분수의 덧셈의 getGCD 참고
public static getGCD(int num1, int num2) {
if (num1 % num2 == 0) return num2;
return getGCD(num2, num1 % num2);
}
class Solution {
public int solution(int a, int b) {
b /= getGCD(a, b);
while (b != 1) {
if (b % 2 == 0) {
b /= 2;
continue;
}
if (b % 5 == 0) {
b /= 5;
continue;
}
return 2; // 조건문들을 통과하지 않았다면 이 곳으로 온다
}
return 1; // 유한 소수 조건에 만족하면 이 곳으로 온다.
}
}